#pragma once

class CLManager;
class Shader;
class GameManager;

#include <list>

struct ParticleSim
{
    glm::vec4 speed;
};

struct ParticleStore
{
    ParticleStore(float ttl, size_t count) 
        : ttl(ttl), count(count) {}
    float ttl;
    size_t count;
};

class ParticleSystem
{
public:
    ParticleSystem();
    ~ParticleSystem();
    void render(float dt);
    void update(float dt);
    void installKernels();

    void addParticles(const glm::vec3& pos, float posRandomness, const glm::vec3& speed, float speedRandomness, float ttl, unsigned int count);

private:
    void initVBO();

private:
    CLManager* clManager;
    GameManager* gm;

    cl::Program program;
    cl::Kernel particleKernel;
    cl::Kernel copyKernel;
    cl::BufferGL renderBuffer;
    cl::Buffer simBuffer;
    GLuint glBuf;
    GLuint vao;
    cl::Image2DGL clTex;

    unsigned int dim;

    Shader* shader;

    std::list<ParticleStore> particleStoreList;
    unsigned int activePtr;
    unsigned int freePtr;
    float maxTtl;
    size_t bufSize;
};

